Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Printing Extensions and Drivers /
Chapter 3 - Printer Drivers / The QuickDraw GX ImageWriter II Printer Driver Messages


Displaying Status Information and the Printing Alert Boxes

You can report status information to the user during the printing process to keep the user informed. Informative text about the printing status is displayed in the desktop printer window.

In addition, when the user has to perform an action before printing can continue, your driver may need to display a printing alert box. You process a printing alert following this sequence of actions:

  1. Make a status record that contains the request to the user.
  2. Call the GXAlertTheUser function to display the status information in a printing alert box. The GXAlertTheUser function is described on page 5-18 in the chapter "Printing Functions for Message Overrides."
  3. Keep sending the printing alert (repeatedly call GXAlertTheUser) until one of three actions occurs:

    • The condition resolves itself.
    • The user responds by clicking a button in the printing alert box.
    • An error of some sort occurs.

  4. If necessary, call GXAlertTheUser again with other informational text so that the user can dismiss the printing alert box. You need to do this if an error occurred or if the problem resolved itself. If the user dismisses the printing alert box, you don't need to take this step.

In the ImageWriter II printer driver, the SD_StartSendPage function displays a printing alert box when the user has to manually feed a page into the printing device,
as shown in Listing 3-15.

Listing 3-15 Displaying a printing alert box with printer status information

{
      StatusRecordPtr      pStat;
         
   /* make a status record with the request to the user */
   pStat = (StatusRecordPtr) NewPtrClear(sizeof(gxStatusRecord) +
                                    sizeof(gxManualFeedRecord));
   anErr = MemError();
   nrequire(anErr, NewPtrClear);
   /* use the built-in status resource for this */
   pStat->statResId = gxUnivAlertStatusResourceId;
   pStat->dialogResult = nil;

   if (!paperFeed.AutoFeed)
      {
      gxManualFeedRecord *pFeed;

      /* use the provided manual-feed alert text string */
      pStat->statResIndex = gxUnivManualFeedIndex;
      pStat->bufferLen  = sizeof(gxManualFeedRecord);
      pFeed = (gxManualFeedRecord*)&pStat->statusBuffer;
      /* the user can choose to switch to auto feed */
      pFeed->canAutoFeed = true;
      GXGetPaperTypeName(GXGetFormatPaperType(pageFormat),
                                       pFeed->paperTypeName);
      }
   else
      {
      gxOutOfPaperRecord *pOut;

      pStat->statResIndex = gxUniveOutOfPaperIndex;
      pStat->bufferLen = sizeof(gxOutOfPaperRecord);
      pOut = (gxOutofPaperRecord *)&pStat->statusBuffer;
      GXGetPaperTypeName(GXGetFormatPaperType(pageFormat,
                                       pOut->paperTypeName);
      }
   
   do /* loop, sending the alert until it gets resolved */
      {
      anErr = GXAlertTheUser(pStat);

      /* if the paper suddenly got loaded, do an OK */
      if (commType == 'PPTL')
         {
         FetchStatusString(&statusReturn, true);
         if ((statusReturn & kOutOfPaperMask) == 0)
            {
            pStat->dialogResult = ok;
            anErr = noErr;
            }
         }
      } while ((anErr == noErr) && (pStat->dialogResult == nil));
   
      /* decide what to do, based on the user's response */
   switch ( pStat->dialogResult )
      {
      case ok:                /* the paper is now loaded */
         break;
         
      case cancel:            /* user wants to stop printing */
         anErr = gxPrUserAbortErr;
         break;
         
      case gxAutoFeedButtonId:/* do rest of job with auto feed */
         paperFeed.gxAutoFeed = true;
         (void) AddCollectionItem(jobCollection, gxPaperFeedTag,
                           gxPrintingTagID, itemSize, &paperFeed);
         break;
      }
      
   DisposPtr((Ptr) pStat); /* done with status now, so dispose */
   }
/* now display the "Sending data to the printer" text */
if (anErr == noErr)
   anErr = GXReportStatus(kDriverStatus, kSendingData);
...
}
This printing alert box makes use of one of the built-in alert conditions that are defined for printer drivers. Table 3-6 lists the predefined alert conditions, each of which is an index into the corresponding informational text strings stored in a predefined printing alert ('plrt') resource.
Table 3-6 Predefined alert conditions for printing device drivers
ConstantValueExplanation
gxUnivManualFeedIndex2Paper needs to be manually fed into the printing device
gxUnivFailToPrintIndex3The printing device could not print
the job
gxUnivPaperJamIndex4A paper jam has occurred on the printing device
gxUnivOutOfPaperIndex5The printing device is out of paper
gxUnivNoPaperTrayIndex6The required paper tray is not in place
gxUnivPrinterReadyIndex7The printing device is ready to print

You can add your own informational text to use with the GXAlertTheUser function by defining printing alert ('plrt') resources, which are described in the chapter "Printing Resources" in this book.

Checking for When an Alert Condition Resolves Itself

Listing 3-15 on page 3-42 includes a loop that continues to call GXAlertTheUser to display the printing alert box until the user feeds the paper. If you are using a printing device that can automatically detect paper feeding, you could change the loop as shown in Listing 3-16.

Listing 3-16 Checking if an alert condition has resolved itself

do
{
   anErr = GXAlertTheUser(pStatus);
   /* see if the user has loaded the paper */
   if ((anErr == noErr) && (pStatus->dialogResult ==nil))
      {
         Boolean userFedPaper;
   
         userFedPaper = CheckToSeeIfPaperWasFed();
         if (userFedPaper) 
            {
            pStatus->statResIndex = gxUnivPrinterReadyIndex;
            anErr = GXAlertTheUser(pStatus);
            pStatus->dialogResult = ok;
            }
      }
} while ((pStatus->dialogResult == nil) && (anErr == noErr));
In this version of the alert loop, the driver calls the CheckToSeeIfPaperWasFed function, which detects if the user has fed a page of paper into the printing device. When this happens, the manual-feed text string in the printing alert box is replaced with the string "Printer is ready," which the user can hide at any time.

Filling In Alert Information at Run Time

When you display a printing alert box and you need to dynamically fill in parts of the alert text string, you have to override two messages:

You can also override the GXHandleAlertFilter message to work with any controls that have been installed in the printing alert box. This message is described on page 4-168 in the chapter "Printing Messages."

Listing 3-17 shows portions of the overrides for these messages that could be used to tell the user that a new pen carousel needs to be placed in a plotter.

Listing 3-17 Modifying alert information at run time

OSErr MyInitializeStatusAlert( StatusRecordPtr pStatus,
                                 DialogPtr *pDialog )
{
   OSErr anErr = noErr;
   
   /* first see if this message is for your driver */
   if (pStatus->statusOwner == kDrvrCreatorType)
      {  
      if (pStatus->statusId == kChangeCarouselsDlogID)
         {
         *pDialog = GetNewDialog( kChangeCarouselsDlogID, nil,
                                 (WindowPtr)-1);
         if (*pDialog == nil)
            anErr = resNotFound;
         else     /* fill in run-time information */
            FillInDialogStrings( pStatus, pDialog );
         }
      else...     /* handle other status conditions */

      }
   else           /* the status text belongs to someone else */
      Forward_GXInitializeStatusAlert( pStatus, pDialog );
      
   return( anErr );
}

OSErr MyHandleAlertEvent( StatusRecordPtr pStatus, DialogPtr
               *pDialog, EventRecord *theEvent, short *itemHit )
{
   OSErr anErr = noErr;

   /* first see if this message is for your driver */
   if (pStatus->statusOwner == kDrvrCreatorType)
      {
      if (pStatus->statusId == kChangeCarouselsDlogID)
         {
         HandleCarouselDialogEvent( pDialog, theEvent, itemHit );
         pStatus->dialogResult = *itemHit;
         }
      else.../* handle other status condition events */

      }
   else     /* the status message belongs to someone else */
      Forward_GXHandleAlertEvent( pStatus, pDialog, theEvent,
                                                      itemHit );
      
   return( anErr );
}
Each of these functions first checks if the status condition is one that it handles. If not,
the condition is passed on to the next handler in the message chain. If the condition is one that the driver handles, the function performs the needed operation: either filling in the name of the carousel that needs to be displayed in the printing alert box or handling an event in the alert box. If the driver handles the alert in these functions, it does not forward the message to the other message handlers.

Displaying Status Text During Printing

When you want to display status information to the user and it does not require a response, you can call the GXReportStatus function, providing it with the ID of a status resource and the ID of the static text in that resource that you want sent to the desktop printer window.

QuickDraw GX provides several status ('stat') resources with a number of predefined text strings that you can display to the user. The printer-status text strings, which are listed in Table 3-7, are located in the page transmission status resource. Some of these strings are repeated, with one entry associated with an alert condition, and the other used to display informational status.
Table 3-7 Status text IDs in the page transmission status resource
Text IDText string
1"Waiting for the next sheet of paper..."
2"Sending part of the page..."
3"Preparing part of the page..."
4"The printer is out of paper."
5"The printer has a paper jam."
6"The paper tray is improperly loaded."
7"The printer door is open. Please close it." (alert version)
8"The printer door is open. Please close it." (status version)
9"A print test is in progress. Please wait..."
10"The printer fixing unit is being heated. Please wait..."
11"The toner cartridge is improperly loaded." (alert version)
12"The toner cartridge is improperly loaded." (status version)
13"Printing the page."
14"Trying to locate the printer..."
15"Opening a connection to the printer..."


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help